﻿using System;
using System.Collections.Generic;
using System.Text;
using TCCHWLib.Commands;
using TCCHWLib;
using System.Windows.Forms;

namespace TCCCompiler
{
    public class Term:IExpression
    {
        TreeNode Current_Node;
        List<Factor> factors = new List<Factor>();
        List<string> operators = new List<string>();
        bool t_for=false;
        string t_for_index;
        bool is_arr=false;

        public Term(TreeNode node,BatchCommand batch,bool T_for,string T_for_index,bool Is_arr)
        {
            Current_Batch = batch;
            Current_Node = node;
            t_for = T_for;
            t_for_index = T_for_index;
            is_arr = Is_arr;
            generate_Term();
            evaluate_Term();
        }
        public void generate_Term()
        {
            for (int i = 0; i < Current_Node.Nodes.Count; i++)
            {
                switch (Current_Node.Nodes[i].Text)
                {
                    case "Factor":
                    case "ConditionFactor":
                        Factor factor = new Factor(Current_Node.Nodes[i],Current_Batch,t_for,t_for_index,is_arr);
                        Current_Batch=factor.Get_Factor();
                        factors.Add(factor);

                        break;
                    case "Operator":
                    case "ConditionOperator":
                        operators.Add(Current_Node.Nodes[i].Nodes[0].Text.Trim());
                        break;
                }
            }
            
        }
        
        public void  evaluate_Term()
        {
            ParameterType parameter1_type;
            ParameterType parameter2_type;

            object parameter_1 = factors[0].Value;

           
            if (factors.Count == 1)
            {
                this.Type = factors[0].Type;
                this.Value = parameter_1;
                return;
            }
            parameter1_type = factors[0].Type;
            factors.RemoveAt(0);
            object parameter_2;

            for (int i = 0; i < factors.Count; i++)
            {
                parameter_2=factors[i].Value;
                parameter2_type = factors[i].Type;

                switch (operators[i].Trim())
                {
                    //case "+":
                    //    AddCommand ADD = new AddCommand(parameter_1, parameter1_type, parameter_2, parameter2_type);
                    //    Current_Batch.AddCommand(ADD);
                    //    parameter_1 = Current_Batch.CommandList.Count-1;
                    //    parameter1_type = ParameterType.Instruction;
                    //    break;

                    //case "-":
                    //    SubCommand SUB = new SubCommand(parameter_1, parameter1_type, parameter_2, parameter2_type);
                    //    Current_Batch.AddCommand(SUB);
                    //    parameter_1 = Current_Batch.CommandList.Count - 1;
                    //    parameter1_type = ParameterType.Instruction;
                    //    break;
                            
                    case "/":
                        DivCommand DIV = new DivCommand(parameter_1, parameter1_type, parameter_2, parameter2_type);
                        Current_Batch.AddCommand(DIV);
                        parameter_1 = Current_Batch.CommandList.Count - 1;
                        parameter1_type = ParameterType.Instruction;
                        break;

                    case "*":
                        MulCommand MUL = new MulCommand(parameter_1, parameter1_type, parameter_2, parameter2_type);
                        Current_Batch.AddCommand(MUL);
                        parameter_1 = Current_Batch.CommandList.Count - 1;
                        parameter1_type = ParameterType.Instruction;
                        break;

                    case "==":
                        EqualCommand equal = new EqualCommand(parameter_1, parameter1_type, parameter_2, parameter2_type);
                        Current_Batch.AddCommand(equal);

                        parameter_1 = Current_Batch.CommandList.Count - 1;
                        parameter1_type = ParameterType.Instruction;
                        break;

                    case "<=":
                        LessThanOrEqualCommand lessThanOrEqual = new LessThanOrEqualCommand(parameter_1, parameter1_type, parameter_2, parameter2_type);
                        Current_Batch.AddCommand(lessThanOrEqual);
                        parameter_1 = Current_Batch.CommandList.Count - 1;
                        parameter1_type = ParameterType.Instruction;
                        break;

                    case "<":
                        LessThanCommand lessThan = new LessThanCommand(parameter_1, parameter1_type, parameter_2, parameter2_type);
                        Current_Batch.AddCommand(lessThan);

                        parameter_1 = Current_Batch.CommandList.Count - 1;
                        parameter1_type = ParameterType.Instruction;
                        break;
                    case ">=":

                        GreaterThanOrEqualCommand greaterThanOrEqual = new GreaterThanOrEqualCommand(parameter_1, parameter1_type, parameter_2, parameter2_type);
                        Current_Batch.AddCommand(greaterThanOrEqual);

                        parameter_1 = Current_Batch.CommandList.Count - 1;
                        parameter1_type = ParameterType.Instruction;
                        break;
                    case ">":
                        GreaterThanCommand greaterThan = new GreaterThanCommand(parameter_1, parameter1_type, parameter_2, parameter2_type);
                        Current_Batch.AddCommand(greaterThan);

                        parameter_1 = Current_Batch.CommandList.Count - 1;
                        parameter1_type = ParameterType.Instruction;
                        break;
                    case "!=":
                        NotEqualCommand notEqual = new NotEqualCommand(parameter_1, parameter1_type, parameter_2, parameter2_type);
                        Current_Batch.AddCommand(notEqual);

                        parameter_1 = Current_Batch.CommandList.Count - 1;
                        parameter1_type = ParameterType.Instruction;
                        break;
                }
            }
            this.Type = ParameterType.Instruction;
            this.Value = this.Current_Batch.CommandList.Count - 1;
            
        }
    }
}
